package com.kate.mall.bff.wx.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.map.MapUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kate.mall.bff.wx.dto.UserDTO;
import com.kate.mall.bff.wx.feign.AuthCenterFeignClient;
import com.kate.mall.bff.wx.feign.MemberFeignClient;
import com.kate.mall.bff.wx.form.WxLoginForm;
import com.kate.mall.common.utils.IpUtil;
import com.kate.mall.common.utils.ListMap2ListVoUtils;
import com.kate.mall.common.utils.ListMap2VoUtil;
import com.kate.mall.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.context.ApplicationContext;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: 用一句话描述
 * @Auther: 新梦想*陈超
 * @Date: 2021/11/1 16:26
 */
@Service
@Slf4j
public class LoginService {

    @Resource
    private WxMaService wxMaService;

    @Resource
    private AuthCenterFeignClient authCenterFeignClient;

    @Resource
    private MemberFeignClient umsFeignClient;


    @Resource
    private ObjectMapper objectMapper;
    @Resource
    private ListMap2VoUtil listMap2VoUtil;
    public R loginByWeixin(WxLoginForm wxLoginForm, HttpServletRequest request) throws WxErrorException {
        //TODO 1.获取微信小程序传递过来的code
        log.info("wxLoginForm====>"+wxLoginForm);
        //TODO 2.根据code appid appsecret 获取openid
        WxMaJscode2SessionResult session   =
                wxMaService.getUserService().getSessionInfo(wxLoginForm.getCode());
        log.info("sessionKey===>"+session.getSessionKey());
        log.info("openId=====>"+session.getOpenid());
        String  openid = session.getOpenid();
        //TODO 3.检测openid是否在ums_member表,不存在，则：注册，存在你 则：更新
        R memberR= umsFeignClient.queryMemeberByOpenId(openid);
        List<Map> memberListMap = MapUtil.get((Map) memberR.get("page"), "list", List.class);
        List<UserDTO> userDTOList = listMap2VoUtil.<UserDTO>map2vo(memberListMap, UserDTO.class);
        userDTOList = objectMapper.convertValue(userDTOList,new TypeReference<List<UserDTO>>(){});
        if(userDTOList!=null&&userDTOList.size()>0){//此微信用户存在,更新用户信息
            UserDTO existUserDTO = userDTOList.get(0);
            existUserDTO.setAvatar(wxLoginForm.getUserInfo().getAvatarUrl());
            existUserDTO.setGender(wxLoginForm.getUserInfo().getGender());
            existUserDTO.setNickname(wxLoginForm.getUserInfo().getNickName());
            existUserDTO.setLastLoginTime(new Date());
            R updateR = umsFeignClient.updateUserInfo(userDTOList.get(0));

            if (MapUtil.get(updateR,"errno",Integer.class).equals(0)) {
                log.info("获取微信用户 openid  ,更新用户信息成功.....");
            }
        }else{// 不存在就添加用户信息
            PasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
            R updateR = umsFeignClient.saveUserInfo(new UserDTO()
                    .setAvatar(wxLoginForm.getUserInfo().getAvatarUrl())
                    .setGender(wxLoginForm.getUserInfo().getGender())
                    .setNickname(wxLoginForm.getUserInfo().getNickName())
                    .setUsername(openid)
                    .setPassword(passwordEncoder.encode(openid))
                    .setWeixinOpenid(openid)
                    .setLastLoginTime(new Date())
                    .setUserLevel(1)
                    .setStatus(0)
                    .setLastLoginIp(IpUtil.getIpAddr(request))
                    .setSessionKey(session.getSessionKey()));

            if (MapUtil.get(updateR,"errno",Integer.class).equals(0)) {
                log.info("获取微信用户 openid  ,保存用户信息成功.....");
            }

        }
        //TODO 4.向认证服务器发送获取token的请求，返回token和refresh_token
        HashMap<String, String> param = MapUtil.newHashMap();
        param.put("client_id",wxLoginForm.getClient_id());
        param.put("client_secret",wxLoginForm.getClient_secret());
        param.put("username",openid);
        param.put("password",openid);
        param.put("grant_type","password");
        R tokenR = authCenterFeignClient.postAccessToken(param);
        log.info("r====>"+tokenR);
        Map loginResult =MapUtil.newHashMap(2);
        loginResult.put("userInfo",wxLoginForm.getUserInfo());
        String token = MapUtil.get((Map) tokenR.get("data"), "token", String.class);
        String refresh_token = MapUtil.get((Map) tokenR.get("data"), "refreshToken", String.class);
        loginResult.put("token",token);
        loginResult.put("refresh_token",refresh_token);
        return R.ok("登录成功").put("data",loginResult);
    }

    public R logout(WxLoginForm wxLoginForm) {
        log.info("微信用户登录成功......");
        R tokenR = authCenterFeignClient.logout();
        if(MapUtil.get(tokenR,"errno",Integer.class).equals(0)){
            return R.ok("退出成功！");
        }
        return  R.error("登出失败 ！！");
    }
}
